package com.gxs.tga.poc.rest;

import java.util.ArrayList;
import java.util.List;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.gxs.tga.poc.domain.TgaCompany;
import com.gxs.tga.poc.domain.TgaSolution;
import com.gxs.tga.poc.domain.dto.TgaSolutionDto;
import com.gxs.tga.poc.domain.exceptions.DuplicateTgaSolution;
import com.gxs.tga.poc.domain.exceptions.InvalidClientRequest;
import com.gxs.tga.poc.rest.common.TgaRestResponse;
import com.gxs.tga.poc.service.TgaCompanyService;
import com.gxs.tga.poc.service.TgaSolutionService;

@Component("tgaSolutionRestBean")
@Path("/solutions")
public class TgaSolutionRestBean
{
	@Autowired
	private TgaSolutionService tgaSolutionService;
	
	@Autowired
	private TgaCompanyService tgaCompanyService;

	@GET
	@Produces(MediaType.APPLICATION_JSON)
	public Response getAllSolutions(@QueryParam("compId")String compId)
	{
		try
		{
			List<TgaSolution> list = null;
			
			if(compId == null )
			{
				list = this.tgaSolutionService.findAll();
			}
			else
			{
				TgaCompany company = this.tgaCompanyService.findById(compId);
				if(company == null)
				{
					throw new InvalidClientRequest("Error: The specified company with compId = " + compId + " does not exist");
				}
				
				list = this.tgaSolutionService.findByTgaCompany(company);
			}
			List<TgaSolutionDto> returnList = new ArrayList<TgaSolutionDto>();
			for(TgaSolution s : list)
			{
				returnList.add(new TgaSolutionDto(s));
			}
			return Response.status(Status.OK).entity(returnList).build();
		}
		catch(Exception e)
		{
			e.printStackTrace();
			int statusCode = 500;
			TgaRestResponse response = new TgaRestResponse(statusCode, "Error Occurred: " + e.getMessage(), statusCode);
			return Response.status(statusCode).entity(response).build();
		}
	}

	@GET
	@Path("/{solutionId}")
	@Produces(MediaType.APPLICATION_JSON)
	public Response getSingleSolutionById(@PathParam("solutionId") String solutionId)
	{
		TgaSolution tgaSolution = this.tgaSolutionService.findById(solutionId);
		if (tgaSolution == null)
		{
			int statusCode = 404;
			TgaRestResponse response = new TgaRestResponse(statusCode, "No record of type 'TgaSolution' (Solution) exists with the id: " + solutionId, statusCode);
			return Response.status(statusCode).entity(response).build();
		} else
		{
			return Response.status(200).entity( new TgaSolutionDto(tgaSolution)  ).build();
		}

	}

	@POST
	@Consumes(MediaType.APPLICATION_JSON)
	@Produces(MediaType.APPLICATION_JSON)
	public Response createOrUpdateSolution(TgaSolutionDto dto, @QueryParam("operation") String operation) throws InvalidClientRequest 
	{
		
		if(operation == null )
		{
			throw new InvalidClientRequest("Missing Query Parameter: 'operation' -- must be provided. Valid Values are: [create, update]");
		}
		else if(operation.equals("create") || operation.equals("update"))
		{
			// good
		}
		else
		{
			throw new InvalidClientRequest("Incorrect value for Query Parameter: 'operation' -- must be provided. Valid Values are: [create, update]");
		}
 
		if(operation.equals("update"))
		{
			throw new InvalidClientRequest("Work In Progress: Update operation is currently in development");
		}
		
		try
		{
			// Check if a valid company exists
			// Database constraint is there anyway - but checking here allows us togive a meaningful message
			String companyId = dto.getCompId();
			
			if(companyId == null)
			{
				throw new InvalidClientRequest("Error: A Valid company id ('compId') must be provided when creating a new solution");
			}
			
			TgaCompany company = this.tgaCompanyService.findById(companyId);
			
			if(company == null)
			{
				throw new InvalidClientRequest("Error: No company record was found for the specified company id: " + companyId);
			}
			
			TgaSolution newSolution = new TgaSolution(dto, company);
			
			
			this.tgaSolutionService.create(newSolution);
			
			int statusCode  = Response.Status.CREATED.getStatusCode();
			
			TgaSolutionDto dtoToReturn = new TgaSolutionDto(newSolution) ;
			
			TgaRestResponse response = new TgaRestResponse(statusCode, "A Solution with solutionId " + newSolution.getSolutionId() + " has been created");
			response.setTargetResource(dtoToReturn);
			response.setTargetResourceRefId(newSolution.getSolutionId());
			response.setTargetResourcePKAttributeName("solutionId");
			
			
			return Response.status(statusCode).entity(   response   ).build();
		}
		catch(DuplicateTgaSolution dte)
		{
			int statusCode  = Response.Status.CONFLICT.getStatusCode();
			TgaRestResponse response = new TgaRestResponse(statusCode, "Error: Solution with id: " + dto.getSolutionId() + " already exists" , statusCode);
			return Response.status(statusCode).entity(response).build();

		}
		
		
	}
	
	
 
}
